# Реализация системы мониторинга с использованием Spring Kafka

## Цель
Создать систему мониторинга, которая будет отслеживать работу различных компонентов вашего приложения с помощью Spring Kafka. Эта система будет включать в себя Producer для отправки метрик, Consumer для их обработки и анализа, а также REST API для просмотра и анализа метрик.

## Общая архитектура системы

### Producer Service

```Генерация метрик:```
данные метрик генерируются с использованием **DataMetricEventsGenerateService**. В текущей реализации набор метрики ограницен следующим списком:
- *jvm.memory.used*,
- *jvm.memory.max*,
- *system.cpu.usage*,
- *system.memory.usage*,
- *jvm.gc.pause*.
 
Метод **scheduleDataMetricEvents** настраивает периодическую генерацию данных метрик с интервалом в 5 секунд с использованием **ThreadPoolTaskScheduler**(интервал можно изменить, например значительно увеличить и отправлять данные через REST API).

 ```Обработка данных:```
  метод **createAndSendDataMetricEvents** собирает метрики, разбивает их на батчи и отправляет в Kafka.
  Метод **getBatches** разбивает список метрик на небольшие списки для более эффективной обработки и отправки.


 
### Consumer Service

Создан микросервис "Consumer", который будет принимать метрики из Kafka топика `Product-created-events.topic` и анализировать их для выявления проблем и трендов. Реализована обработка метрик и вывод статистики в логи и базу данных для последующего анализа.

### Modelsources
В данный модуль вынесена модель данных, используемая как продюсером, так и консьюмером 

### REST API

- реализован REST-метод **POST /metrics** в `Producer` для взаимодействия с микросервисом: получение данных из вне в формате JSON. Метрики могут включать информацию о производительности, использовании ресурсов, ошибках и т. д. Пример JSON для внешних данных будет приведен ниже

- Реализован REST API в `Consumer` для просмотра метрик:

- **GET /metrics:** Получение списка всех метрик.
- **GET /metrics/{metricName}:** Получение конкретной метрики по ее имени.
- **GET /metrics/{metricName}/max:** Получение максимального значения поля 'measurement'(численное значение измерения) конкретной метрики по ее имени.
- **GET /metrics/{metricName}/min:** Получение минимального значения поля 'measurement'(численное значение измерения) конкретной метрики по ее имени.
- **GET /metrics/{metricName}/avg:** Получение среднего значения поля 'measurement'(численное значение измерения) конкретной метрики по ее имени.

## Запуск и настройка

1. Убедитесь, что у вас установлен и настроен Docker/Kafka/
2. У обоих микросервисов,"Producer" и "Consumer", используются рандомные порты (server.port=0), желательно при запуске каждого успеть их сохранить для дальнейшего обращения через postman/браузер 
4. Запустите оба микросервиса и начните отправку и потребление метрик.


## Заключение
- *Масштабируемость:* использование 3 разделов позволяет распределять нагрузку и обрабатывать сообщения параллельно, что увеличивает производительность и масштабируемость системы.
- *Надежность:* настройка 3 реплик и параметра acks=all в сочетании с min.insync.replicas=2 обеспечивает высокую надежность и отказоустойчивость системы. Включение идемпотентности гарантирует точную однократную доставку сообщений.
- *Производительность:* конфигурация таймаутов и пула потоков помогает контролировать и оптимизировать производительность системы, обеспечивая эффективное использование ресурсов.

  ## Пример метрик

Пример JSON для отправки данных посредством REST-API, предоставленного `Producer`:

```json
[
        {
            "metricName":"jvm.memory.used",
            "tags":{"area":"nonheap","id":"CodeCache"},
            "measurement":9299072.0
        },
        {
            "metricName":"jvm.memory.used",
            "tags":{"area":"heap","id":"G1 Old Gen"},
            "measurement":1.4887936E7
        },
        {
            "metricName":"jvm.memory.max",
            "tags":{"area":"nonheap","id":"Metaspace"},
            "measurement":-1.0
        },
        {
            "metricName":"jvm.memory.max",
            "tags":{"area":"heap","id":"G1 Survivor Space"},
            "measurement":-1.0
        },
        {
            "metricName":"jvm.memory.max",
            "tags":{"area":"heap","id":"G1 Old Gen"},
            "measurement":2.092957696E9
        }
]
